package com.wq.proxy.jdk;

import sun.misc.ProxyGenerator;

import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: wangqiang20995
 * @Date:2018/9/27
 * @Description:
 * @Resource:
 */
public class ProxyHandler implements InvocationHandler {

    private CommonService commonService;

    public ProxyHandler(CommonService commonService) {
        this.commonService = commonService;
    }

    public ProxyHandler() {}

    public void setCommonService(CommonService commonService) {
        this.commonService = commonService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy object is --> [" + this.commonService.getClass().getName() + "]");
        System.out.println("call proxy method --> [" + method.getName() + "]");
        System.out.println("invoke method param proxy is --> [" + proxy.getClass().getName() + "]");
        Object response = null;
        try {
            response = method.invoke(commonService, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    public <T> T proxy(Class<T> proxyObject) {
        return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{proxyObject}, this);
    }

    public static void main(String args[]) throws IOException {
        CommonService commonService = new DefaultCommonService();
        ProxyHandler invocationHandler = new ProxyHandler(commonService);
        CommonService proxyObject = invocationHandler.proxy(CommonService.class);
        System.out.println("proxy object class --> [" + proxyObject.getClass() + "]");
        Map<String, Object> map = new HashMap<>();
        map.put("type", 1);
        proxyObject.display(map);
        System.out.println("--------------------call proxy object-------------------");
        proxyObject.postService(1);

        byte[] classData = ProxyGenerator.generateProxyClass("com.sun.proxy.$Proxy0",new Class[]{CommonService.class});
        OutputStream outputStream = new FileOutputStream(new File("D://com.sun.proxy.$Proxy0.class"));

        outputStream.write(classData);
        outputStream.flush();

        outputStream.close();
    }
}
